Datadog エージェントと AWS Secrets Manager を連携して安全なシークレット管理を実現してみた

Datadog エージェントと AWS Secrets Manager を連携して安全なシークレット管理を実現してみた

Clock Icon2024.09.09

こんにちは。テクニカルサポートチームのShiinaです。

はじめに

Datadog では リレーショナルデータベースのクエリパフォーマンスやスループット、接続、エラーのモニタリングを行うことができます。
モニタリングを行うためには Datadog エージェントの構成ファイルにデータベースの認証情報を指定する必要があります。
データベースの認証情報(ユーザー名、パスワード等)をプレーンテキストで保存することはセキュリティー的に好ましくありません。
Datadog エージェントの secret パッケージを利用すると、データベースの認証情報などのシークレット情報をセキュアに取り扱うことができます。
今回は Datadog エージェントと AWS Secrets Manager を連携させて安全なシークレット管理を実現する方法についてご紹介します。

概要

AWS Secrets Manager に登録した Amazon RDS for MySQL の認証情報を AWS CLI コマンドを利用して取得するスクリプトを用意します。
用意したスクリプトを Datadog エージェントが実行できるようにの設定を行います。
Datadog エージェントの構成ファイルに対してはシークレット情報を指定して MySQL に接続を行いモニタリングを行います。

前提

本記事では以下を前提としています。

  • AWS Secrets Manager のシークレット名は次のように扱います。
    ユーザー名: dbuser
    パスワード: dbpassword
    ※シークレット名は任意の名前を利用することが可能です。
    手順内で上記が設定値となっている箇所は読み替えてください。

  • MySQL にユーザが登録されていること

  • Linux 系 OS のインスタンスを利用していること

  • AWS CLI と jq がインストールされていること

  • Datadog エージェントがインストールされていること

  • 東京リージョンを利用していること

  • AWS Secrets Manager のシークレットに対するアクセスには EC2 インスタンスロールの認証情報を利用していること

AWS Secrets Manager へのシークレット登録

AWS CLI コマンドもしくはマネジメントコンソールを利用してデータベースのユーザー名とパスワード情報を AWS Secrets Manager のシークレットに登録します。

  • AWS CLI コマンド
aws secretsmanager create-secret \
    --name "dbuser" \
    --description "Database credentials for Datadog agent" \
    --secret-string "【ユーザー名情報】" \
    --region ap-northeast-1

aws secretsmanager create-secret \
    --name "dbpassword" \
    --description "Database credentials for Datadog agent" \
    --secret-string "【パスワード情報】" \
    --region ap-northeast-1
  • マネジメントコンソール
    シークレットのタイプ:その他のシークレットのタイプ
    キー/値のペア:プレーンテキスト
    dbuser 、dbpassword を名前としたシークレットをそれぞれ登録してください。
    dbuser-Secrets-Manager-Secrets-Manager-ap-northeast-1

EC2 インスタンスロール設定

Datadog エージェントが稼働している EC2 インスタンスから AWS Secrets Manager にアクセスするためには IAM の権限が必要です。
EC2 インスタンスロールにシークレットの読み取りを許可するポリシーをアタッチします。
今回は下記の AWS マネージドポリシーを利用しました。

  • SecretsManagerReadWrite

スクリプトの設定

AWS Secrets Manager からシークレットを取得するスクリプト配置、スクリプトファイルのパーミッションの変更設定を行います。

サンプルスクリプト

AWS CLI コマンドを利用して AWS Secrets Manager からシークレット情報を取得し、jq コマンドで出力を整形します。

get-secret.sh
#!/bin/bash

# デフォルトリージョン(東京リージョンを指定)
defaultregion="ap-northeast-1"
# 標準入力からJSONを読み取る
input=$(cat)

# JSONからsecretsリストを抽出
secrets=$(echo "$input" | jq -r '.secrets[]')

# 結果を格納するJSON
result="{}"

# 各シークレットを処理
for secret in $secrets; do
    # AWS Secrets Managerからシークレットを取得(JSON形式で出力)
    secret_value=$(aws secretsmanager get-secret-value --region "$defaultregion" --secret-id "$secret" --output json 2>&1)
    if [ $? -eq 0 ]; then
        # シークレットの取得に成功した場合
        secret_string=$(echo "$secret_value" | jq '.SecretString')
        result=$(echo "$result" | jq --arg secret "$secret" --argjson value "$secret_string" '. + {($secret): {"value": $value, "error": null}}')
    else
        # シークレットの取得に失敗した場合
        result=$(echo "$result" | jq --arg secret "$secret" --arg error "$secret_value" '. + {($secret): {"value": null, "error": $error}}')
    fi
done

# 結果を出力
echo "$result"

スクリプトの動作

Datadog エージェントの secret パッケージの実行可能な API 仕様に従い、標準入力から JSON を読み取り、復号化されたシークレット情報を含む JSON を標準出力に出力します。

入力例
{"version": "1.0", "secrets": ["<secretsname1>","<secretsname2>"]}
出力例
{
  "<secretsname1>": {
    "value": "<secretsvalue>",
    "error": null
  },
  "<secretsname2>": {
    "value": "<secretsvalue>",
    "error": null
  }
}

スクリプトの配置

1)以下のパスにスクリプトファイルを配置します。

/usr/local/bin/get-secret.sh

2)実行権限を与えるため、パーミッションを変更します。

sudo chmod 700 get-secret.sh

3)Datadog エージェントが実行できるようにスクリプトファイルの所有者を Datadog エージェントのユーザーである dd-agent へ変更します。

sudo chown dd-agent:dd-agent get-secret.sh

テスト方法

1)input.json ファイルを配置します。

input.json
{"version": "1.0", "secrets": ["dbuser","dbpassword"]}

2)input.json ファイルを標準入力としてスクリプトを実行します。

cat input.json | sudo /usr/local/bin/get-secret.sh

3)シークレットが出力されることを確認してください。

sucess
{
  "dbuser": {
    "value": "【ユーザー名情報】",
    "error": null
  },
  "dbpassword": {
    "value": "【パスワード情報】",
    "error": null
  }
}

取得に失敗した場合は error に出力されます。

error
{
  "hoge": {
    "value": null,
    "error": "\nAn error occurred (ResourceNotFoundException) when calling the GetSecretValue operation: Secrets Manager can't find the specified secret."
  }
}

Datadog エージェント(datadog.yaml)の設定

Datadog エージェントが secret パッケージを利用してシークレット情報を取得できるように設定を行います。
datadog.yaml に対して secret_backend_command パラメータを追加し、スクリプトのファイルパスを指定します。

datadog.yaml

(中略)
#########################
## Basic Configuration ##
#########################

secret_backend_command: "/usr/local/bin/get-secret.sh"

(中略)

構成ファイル(conf.yaml)の設定

MySQL のモニタリングを行うため、以下のパスに構成ファイル(conf.yaml)を配置します。

/etc/datadog-agent/conf.d/mysql.d/conf.yaml

モニタリングしたい MySQL の host および port を指定します。
username および passoword の値は 'ENC[シークレットの名前]' となるように指定します。

conf.yaml
init_config:

instances:
  - dbm: true
    host: 'monitor-database.c9s4eucwustm.ap-northeast-1.rds.amazonaws.com'
    port: 3306
    username: 'ENC[dbuser]' 
    password:  'ENC[dbpassword]'
    # After adding your project and instance, configure the Datadog AWS integration to pull additional cloud data such as CPU and Memory.
    aws:
      instance_endpoint: 'monitor-database.c9s4eucwustm.ap-northeast-1.rds.amazonaws.com'

設定の反映

Datadog エージェントの再起動を行い、datadog.yaml および conf.yaml の設定を反映させます。

sudo systemctl restart datadog-agent

設定の確認

正しく設定が反映され、 MySQL のモニタリングが行えているか確認を行います。

構成チェック

sudo datadog-agent configcheck

username と password がマスクされて表示されていることを確認してください。

(中略)
== mysql check ===
Configuration provider: file
Configuration source: file:/etc/datadog-agent/conf.d/mysql.d/conf.yaml
Config for instance ID: mysql:d535bd8b0ca4a66
aws:
  instance_endpoint: monitor-database.c9s4eucwustm.ap-northeast-1.rds.amazonaws.com
dbm: true
host: monitor-database.c9s4eucwustm.ap-northeast-1.rds.amazonaws.com
password: "********"
port: 3306
username: "********"
~
===
(中略)

secret チェック

sudo datadog-agent secret

permission が OK となっていることと、 Secrets handle resolved が表示されていることを確認してください。

=== Checking executable permissions ===
Executable path: /usr/local/bin/get-secret.sh
Executable permissions: OK, the executable has the correct permissions

Permissions Detail:
File mode: 100700
Owner: dd-agent
Group: dd-agent

=== Secrets stats ===
Number of secrets resolved: 2
Secrets handle resolved:

- 'dbpassword':
        used in 'mysql' configuration in entry 'password'
- 'dbuser':
        used in 'mysql' configuration in entry 'username'

status チェック

sudo datadog-agent status

Running Checks の mysql が [OK] と表示されていることを確認してください。

(中略)
=========
Collector
=========
  Running Checks
  ==============
    mysql (12.6.1)
    --------------
      Instance ID: mysql:b5abdf9299f0f776 [OK]
      Configuration Source: file:/etc/datadog-agent/conf.d/mysql.d/conf.yaml
      Total Runs: 5
      Metric Samples: Last Run: 244, Total: 1,092
      Events: Last Run: 0, Total: 0
      Database Monitoring Activity Samples: Last Run: 1, Total: 7
      Database Monitoring Metadata Samples: Last Run: 1, Total: 1
      Database Monitoring Query Metrics: Last Run: 1, Total: 6
      Database Monitoring Query Samples: Last Run: 1, Total: 35
      Service Checks: Last Run: 3, Total: 15
      Average Execution Time : 67ms
      Last Execution Date : 2024-09-04 08:26:06 UTC (1725438366000)
      Last Successful Execution Date : 2024-09-04 08:26:06 UTC (1725438366000)
      metadata:
        flavor: MySQL
        resolved_hostname: monitor-database.c9s4eucwustm.ap-northeast-1.rds.amazonaws.com
        version.build: unspecified
        version.major: 8
        version.minor: 0
        version.patch: 35
        version.raw: 8.0.35+unspecified
        version.scheme: semver
(中略)

プロセスリストチェック

MySQL クライアント等を利用して SQL を実行し、実行されているプロセス情報を確認します。

SELECT * FROM information_schema.PROCESSLIST;

Datadog エージェントが稼働しているホストから AWS Secrets Manager にシークレットとして登録したユーザー名を利用したプロセスが一覧に表示されていることを確認してください。
ユーザー名で datadog を利用した場合は次の通りです。

+----+-----------------+------------------+-------+---------+------+------------------------+----------------------------------------------+
| ID | USER            | HOST             | DB    | COMMAND | TIME | STATE                  | INFO                                         |
+----+-----------------+------------------+-------+---------+------+------------------------+----------------------------------------------+
| 24 | admin           | 10.0.0.196:47564 | NULL  | Query   |    0 | executing              | SELECT * FROM information_schema.PROCESSLIST |
| 17 | datadog         | 10.0.0.196:60580 | NULL  | Sleep   |    1 |                        | NULL                                         |
|  9 | rdsadmin        | localhost        | mysql | Sleep   |    6 |                        | NULL                                         |
|  5 | event_scheduler | localhost        | NULL  | Daemon  |  175 | Waiting on empty queue | NULL                                         |
| 14 | datadog         | 10.0.0.196:40088 | NULL  | Sleep   |    1 |                        | NULL                                         |
| 15 | datadog         | 10.0.0.196:40102 | NULL  | Sleep   |    0 |                        | NULL                                         |
+----+-----------------+------------------+-------+---------+------+------------------------+----------------------------------------------+
6 rows in set, 1 warning (0.001 sec)

まとめ

Datadog エージェントに対して AWS Secrets Manager を利用した安全なシークレット管理をやってみました。

最後までご覧いただきありがとうございました。
本記事が誰かのお役に立てれば幸いです。

参考

https://docs.datadoghq.com/agent/configuration/secrets-management/?tab=linux

https://docs.datadoghq.com/integrations/mysql/?tab=host

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.